<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::async Namespace Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1async.html">async</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#typedef-members">Typedefs</a> &#124;
<a href="#enum-members">Enumerations</a> &#124;
<a href="#func-members">Functions</a>  </div>
  <div class="headertitle"><div class="title">flow::async Namespace Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-task proactor pattern, by providing a streamlined API around boost.asio event loops with added advanced task- and thread-scheduling features.  
<a href="namespaceflow_1_1async.html#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">The core <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> interface, providing an optionally multi-threaded thread pool onto which runnable <code>Task</code>s, optionally arranged into concurrency-avoiding <code>Op</code>s, can be boost.asio-posted for subsequent execution.  <a href="classflow_1_1async_1_1Concurrent__task__loop.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html">Cross_thread_task_loop</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Concrete <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> that is able to efficiently schedule <code>Task</code>s within a given <code>Op</code> to execute in different threads while still properly avoiding concurrency.  <a href="classflow_1_1async_1_1Cross__thread__task__loop.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Op__list.html">Op_list</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Simple, immutable <code>vector</code>-like sequence of N opaque <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> objects, usually corresponding to N worker threads, with typically used operations such as <code>[index]</code> and random <code>Op</code> selection.  <a href="classflow_1_1async_1_1Op__list.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html">Segregated_thread_task_loop</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Concrete <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> that uses the legacy pin-<code>Task</code>s-within-1-<code>Op</code>-to-1-thread method of achieving required non-concurrency of <code>Task</code>s.  <a href="classflow_1_1async_1_1Segregated__thread__task__loop.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html">Single_thread_task_loop</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">A <code><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a></code>-related adapter-style class that represents a single-thread task loop; essentially it is pleasant syntactic sugar around a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> impl that cuts out concepts that become irrelevant with only one thread involved.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Timed__concurrent__task__loop.html">Timed_concurrent_task_loop</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decorates a general &ndash; potentially multi-threaded &ndash; <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> of any kind but with timing capabilities.  <a href="classflow_1_1async_1_1Timed__concurrent__task__loop.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Timed__concurrent__task__loop__impl.html">Timed_concurrent_task_loop_impl</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Decorator of a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> with same or greater lifetime that accumulates time elapsed in any tasks posted or scheduled onto that loop.  <a href="classflow_1_1async_1_1Timed__concurrent__task__loop__impl.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Timed__single__thread__task__loop.html">Timed_single_thread_task_loop</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html" title="A Concurrent_task_loop-related adapter-style class that represents a single-thread task loop; essenti...">Single_thread_task_loop</a>, but all tasks posted through it are automatically timed, with the result accessible via <a class="el" href="classflow_1_1async_1_1Timed__single__thread__task__loop.html#ae429fb31d17d422306cd9da398e53e5c" title="See Timed_concurrent_task_loop_impl::accumulated_time().">accumulated_time()</a>.  <a href="classflow_1_1async_1_1Timed__single__thread__task__loop.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="typedef-members" name="typedef-members"></a>
Typedefs</h2></td></tr>
<tr class="memitem:af35fb65bdea1a3a92929ec2c4a6a6b72"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> = Function&lt; void()&gt;</td></tr>
<tr class="memdesc:af35fb65bdea1a3a92929ec2c4a6a6b72"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a task that can be posted for execution by a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> or <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">flow::util::Task_engine</a>; it is simply something callable via <code>()</code> with no arguments and returning nothing.  <a href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">More...</a><br /></td></tr>
<tr class="separator:af35fb65bdea1a3a92929ec2c4a6a6b72"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a024042c64b7dc544a7a5587afa4b1949"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> = boost::any</td></tr>
<tr class="memdesc:a024042c64b7dc544a7a5587afa4b1949"><td class="mdescLeft">&#160;</td><td class="mdescRight">An object of this opaque type represents a collection of 1 or more <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72" title="Short-hand for a task that can be posted for execution by a Concurrent_task_loop or flow::util::Task_...">async::Task</a>, past or future, such that: <em>if</em> one performs <code>C-&gt;post(J, F)</code> and <code>C-&gt;post(K, G)</code> (where C is <code>Concurrent_task_loop*</code>, JK are the same <code><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a>&amp;</code>, or one refers to a transitive copy of the other, and FG are both <code>Task</code>s), <em>then</em> F and G will NOT execute concurrently.  <a href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">More...</a><br /></td></tr>
<tr class="separator:a024042c64b7dc544a7a5587afa4b1949"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af8c06052dd887bc77444550a7c243154"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">Scheduled_task</a> = <a class="el" href="namespaceflow_1_1util.html#aafa03984c5012ef7db2e7d01b6909a83">util::Scheduled_task</a></td></tr>
<tr class="memdesc:af8c06052dd887bc77444550a7c243154"><td class="mdescLeft">&#160;</td><td class="mdescRight">Similar to <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72" title="Short-hand for a task that can be posted for execution by a Concurrent_task_loop or flow::util::Task_...">flow::async::Task</a> but used for scheduled-in-future tasks as opposed to to-be-run-ASAP tasks.  <a href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">More...</a><br /></td></tr>
<tr class="separator:af8c06052dd887bc77444550a7c243154"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afdf5986cd6dc055673792890502135a8"><td class="memItemLeft" align="right" valign="top"><a id="afdf5986cd6dc055673792890502135a8" name="afdf5986cd6dc055673792890502135a8"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Task_asio_err</b> = Function&lt; void(const <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09">Error_code</a> &amp;)&gt;</td></tr>
<tr class="memdesc:afdf5986cd6dc055673792890502135a8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a boost.asio completion handler: The minimal type, taking only a <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09" title="Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...">flow::Error_code</a> a/k/a <code>boost::system::error_code</code>. <br /></td></tr>
<tr class="separator:afdf5986cd6dc055673792890502135a8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3808f400a39b77d712e0526fa412bf57"><td class="memItemLeft" align="right" valign="top"><a id="a3808f400a39b77d712e0526fa412bf57" name="a3808f400a39b77d712e0526fa412bf57"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Task_asio_err_sz</b> = Function&lt; void(const <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09">Error_code</a> &amp;, size_t)&gt;</td></tr>
<tr class="memdesc:a3808f400a39b77d712e0526fa412bf57"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a boost.asio completion handler: The type that takes a <code>size_t</code> count of things successfully transferred usually. <br /></td></tr>
<tr class="separator:a3808f400a39b77d712e0526fa412bf57"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a968806f54b14c697fd76b3339a2bdbbf"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> = boost::shared_ptr&lt; <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">util::Task_engine</a> &gt;</td></tr>
<tr class="memdesc:a968806f54b14c697fd76b3339a2bdbbf"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for reference-counting pointer to a mutable <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a <code>boost::asio::io_context</code>).  <a href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">More...</a><br /></td></tr>
<tr class="separator:a968806f54b14c697fd76b3339a2bdbbf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2b92feccafa90bce16db57131c0fcd9e"><td class="memItemLeft" align="right" valign="top"><a id="a2b92feccafa90bce16db57131c0fcd9e" name="a2b92feccafa90bce16db57131c0fcd9e"></a>
using&#160;</td><td class="memItemRight" valign="bottom"><b>Strand_ptr</b> = boost::shared_ptr&lt; <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e">util::Strand</a> &gt;</td></tr>
<tr class="memdesc:a2b92feccafa90bce16db57131c0fcd9e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for ref-counted pointer to <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>. <br /></td></tr>
<tr class="separator:a2b92feccafa90bce16db57131c0fcd9e"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a>
Enumerations</h2></td></tr>
<tr class="memitem:a0a06794b16b72f2829ce3353557c8485"><td class="memItemLeft" align="right" valign="top">enum class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">Synchronicity</a> { <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f">S_ASYNC</a>
, <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25">S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a>
, <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846">S_ASYNC_AND_AWAIT_CONCURRENT_START</a>
, <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485aff6bc53ee6c14f2eee463c06d9dff01f">S_OPPORTUNISTIC_SYNC_ELSE_ASYNC</a>
 }</td></tr>
<tr class="memdesc:a0a06794b16b72f2829ce3353557c8485"><td class="mdescLeft">&#160;</td><td class="mdescRight">Enumeration indicating the manner in which <a class="el" href="namespaceflow_1_1async.html#a24567271e97a67d3cae6bd8bf8dc63c4" title="An extension of boost.asio&#39;s post() and dispatch() free function templates, this free function templa...">asio_exec_ctx_post()</a>, and various boost.asio "post" operations like it or based on it, are to actually execute the given task in relation to when the "posting" routine, itself, returns control to its caller.  <a href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">More...</a><br /></td></tr>
<tr class="separator:a0a06794b16b72f2829ce3353557c8485"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="func-members" name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:a24567271e97a67d3cae6bd8bf8dc63c4"><td class="memTemplParams" colspan="2">template&lt;typename Execution_context &gt; </td></tr>
<tr class="memitem:a24567271e97a67d3cae6bd8bf8dc63c4"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a24567271e97a67d3cae6bd8bf8dc63c4">asio_exec_ctx_post</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, Execution_context *exec_ctx, <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">Synchronicity</a> synchronicity, <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;task)</td></tr>
<tr class="memdesc:a24567271e97a67d3cae6bd8bf8dc63c4"><td class="mdescLeft">&#160;</td><td class="mdescRight">An extension of boost.asio's <code>post()</code> and <code>dispatch()</code> free function templates, this free function template allows the user to more easily select the synchronicity behavior as the given task is posted onto the given execution context (<a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> or <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> at least).  <a href="namespaceflow_1_1async.html#a24567271e97a67d3cae6bd8bf8dc63c4">More...</a><br /></td></tr>
<tr class="separator:a24567271e97a67d3cae6bd8bf8dc63c4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:adab04f47b40b92fffbe12bc33fadd223"><td class="memItemLeft" align="right" valign="top">unsigned int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#adab04f47b40b92fffbe12bc33fadd223">optimal_worker_thread_count_per_pool</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, bool est_hw_core_sharing_helps_algo)</td></tr>
<tr class="memdesc:adab04f47b40b92fffbe12bc33fadd223"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assuming a planned thread pool will be receiving ~symmetrical load, and its UX-affecting (in particular, per-op latency-affecting) operations are largely between processor and RAM: Returns the # of threads to store in that pool for efficient performance.  <a href="namespaceflow_1_1async.html#adab04f47b40b92fffbe12bc33fadd223">More...</a><br /></td></tr>
<tr class="separator:adab04f47b40b92fffbe12bc33fadd223"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3e200db7e5375de21d2568004a85dcad"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a3e200db7e5375de21d2568004a85dcad">optimize_pinning_in_thread_pool</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, const std::vector&lt; <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> * &gt; &amp;threads_in_pool, bool est_hw_core_sharing_helps_algo, bool est_hw_core_pinning_helps_algo, bool hw_threads_is_grouping_collated, <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09">Error_code</a> *err_code=nullptr)</td></tr>
<tr class="memdesc:a3e200db7e5375de21d2568004a85dcad"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assuming the same situation as documented for <a class="el" href="namespaceflow_1_1async.html#adab04f47b40b92fffbe12bc33fadd223" title="Assuming a planned thread pool will be receiving ~symmetrical load, and its UX-affecting (in particul...">optimal_worker_thread_count_per_pool()</a>, and that indeed the pool now contains that number of running threads: Attempts to optimize thread-core-pinning behavior in that pool for efficient performance.  <a href="namespaceflow_1_1async.html#a3e200db7e5375de21d2568004a85dcad">More...</a><br /></td></tr>
<tr class="separator:a3e200db7e5375de21d2568004a85dcad"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7fa5292ae2e7dddd11a7fe5228b1e574"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a7fa5292ae2e7dddd11a7fe5228b1e574">reset_thread_pinning</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr=nullptr, <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> *thread_else_ours=nullptr, <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09">Error_code</a> *err_code=nullptr)</td></tr>
<tr class="memdesc:a7fa5292ae2e7dddd11a7fe5228b1e574"><td class="mdescLeft">&#160;</td><td class="mdescRight">Resets the processor-affinity of the given thread &ndash; or calling thread &ndash; to be managed as the OS deems best.  <a href="namespaceflow_1_1async.html#a7fa5292ae2e7dddd11a7fe5228b1e574">More...</a><br /></td></tr>
<tr class="separator:a7fa5292ae2e7dddd11a7fe5228b1e574"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a227e64eb71ec278f19d679d8411db627"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a227e64eb71ec278f19d679d8411db627">reset_this_thread_pinning</a> ()</td></tr>
<tr class="memdesc:a227e64eb71ec278f19d679d8411db627"><td class="mdescLeft">&#160;</td><td class="mdescRight">Resets processor-affinity of the calling thread; does not log; and throws on extremely unlikely system error.  <a href="namespaceflow_1_1async.html#a227e64eb71ec278f19d679d8411db627">More...</a><br /></td></tr>
<tr class="separator:a227e64eb71ec278f19d679d8411db627"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af90c1e763d49c3f3033a74871e897394"><td class="memTemplParams" colspan="2">template&lt;typename Handler &gt; </td></tr>
<tr class="memitem:af90c1e763d49c3f3033a74871e897394"><td class="memTemplItemLeft" align="right" valign="top">auto&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#af90c1e763d49c3f3033a74871e897394">asio_handler_via_op</a> (<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *loop, const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;op, Handler &amp;&amp;handler)</td></tr>
<tr class="memdesc:af90c1e763d49c3f3033a74871e897394"><td class="mdescLeft">&#160;</td><td class="mdescRight">Given a boost.asio <em>completion handler</em> <code>handler</code> for a boost.asio <code>async_*()</code> action on some boost.asio I/O object to be initiated in the immediate near future, returns a wrapped handler with the same signature to be passed as the handler arg to that <code>async_*()</code> action, so that <code>handler()</code> will execute non-concurrently with other tasks in <code>Op op</code>.  <a href="namespaceflow_1_1async.html#af90c1e763d49c3f3033a74871e897394">More...</a><br /></td></tr>
<tr class="separator:af90c1e763d49c3f3033a74871e897394"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7f2f976a53191a3b0cd28898bb23c551"><td class="memTemplParams" colspan="2">template&lt;typename Exec_ctx_ptr &gt; </td></tr>
<tr class="memitem:a7f2f976a53191a3b0cd28898bb23c551"><td class="memTemplItemLeft" align="right" valign="top">Exec_ctx_ptr&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a7f2f976a53191a3b0cd28898bb23c551">op_to_exec_ctx</a> (<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *loop, const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;op)</td></tr>
<tr class="memdesc:a7f2f976a53191a3b0cd28898bb23c551"><td class="mdescLeft">&#160;</td><td class="mdescRight">Template specialization model for operation that obtains the underlying execution context, such as a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> or <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>.  <a href="namespaceflow_1_1async.html#a7f2f976a53191a3b0cd28898bb23c551">More...</a><br /></td></tr>
<tr class="separator:a7f2f976a53191a3b0cd28898bb23c551"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad70c594985b402d9024b80370611fc1c"><td class="memItemLeft" align="right" valign="top">template&lt;&gt; </td></tr>
<tr class="memitem:ad70c594985b402d9024b80370611fc1c"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#ad70c594985b402d9024b80370611fc1c">op_to_exec_ctx&lt; Task_engine_ptr &gt;</a> (<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *loop, const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;op)</td></tr>
<tr class="memdesc:ad70c594985b402d9024b80370611fc1c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>.  <a href="namespaceflow_1_1async.html#ad70c594985b402d9024b80370611fc1c">More...</a><br /></td></tr>
<tr class="separator:ad70c594985b402d9024b80370611fc1c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5dad6aeb3cf4219833e18343bec0b423"><td class="memItemLeft" align="right" valign="top">template&lt;&gt; </td></tr>
<tr class="memitem:a5dad6aeb3cf4219833e18343bec0b423"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a2b92feccafa90bce16db57131c0fcd9e">Strand_ptr</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a5dad6aeb3cf4219833e18343bec0b423">op_to_exec_ctx&lt; Strand_ptr &gt;</a> (<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *loop, const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;op)</td></tr>
<tr class="memdesc:a5dad6aeb3cf4219833e18343bec0b423"><td class="mdescLeft">&#160;</td><td class="mdescRight">Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>.  <a href="namespaceflow_1_1async.html#a5dad6aeb3cf4219833e18343bec0b423">More...</a><br /></td></tr>
<tr class="separator:a5dad6aeb3cf4219833e18343bec0b423"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ad932f51435b1776625df394e159e7e55"><td class="memItemLeft" align="right" valign="top">template&lt;&gt; </td></tr>
<tr class="memitem:ad932f51435b1776625df394e159e7e55"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#ad932f51435b1776625df394e159e7e55">op_to_exec_ctx&lt; Task_engine_ptr &gt;</a> (<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *loop, const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;op)</td></tr>
<tr class="memdesc:ad932f51435b1776625df394e159e7e55"><td class="mdescLeft">&#160;</td><td class="mdescRight">Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>.  <a href="namespaceflow_1_1async.html#ad932f51435b1776625df394e159e7e55">More...</a><br /></td></tr>
<tr class="separator:ad932f51435b1776625df394e159e7e55"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a05632ba834a42315615900ee4382287d"><td class="memItemLeft" align="right" valign="top">template&lt;&gt; </td></tr>
<tr class="memitem:a05632ba834a42315615900ee4382287d"><td class="memTemplItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a2b92feccafa90bce16db57131c0fcd9e">Strand_ptr</a>&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1async.html#a05632ba834a42315615900ee4382287d">op_to_exec_ctx&lt; Strand_ptr &gt;</a> (<a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *loop, const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;op)</td></tr>
<tr class="memdesc:a05632ba834a42315615900ee4382287d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>.  <a href="namespaceflow_1_1async.html#a05632ba834a42315615900ee4382287d">More...</a><br /></td></tr>
<tr class="separator:a05632ba834a42315615900ee4382287d"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-task proactor pattern, by providing a streamlined API around boost.asio event loops with added advanced task- and thread-scheduling features. </p>
<p >There is also support for single-threaded event loops.</p>
<p >In simpler terms, at its core &ndash; including when the "pool" has just one thread, which is very common &ndash; it provides a compact way of both starting thread(s) <em>and</em> posting/scheduling tasks and I/O to run in such thread(s). By default one must worry about each of those 2 concerns separately and decide how exactly to hook them up; which is not rocket science, but it <em>is</em> a ton of boiler-plate, and it <em>is</em> easy to make mistakes and/or omit useful startup/shutdown practices, logging, and more. This module provides, via <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> and its implementations, at least that consistency/standardization. Plus, it provides certain advanced features as mentioned above.</p>
<ul>
<li>boost.asio provides the core algorithmic abilities of an optionally multi-threaded task-executing loop, particularly through classes <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a <code>boost::asio::io_context</code>), <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> (a/k/a <code>strand</code> in <code>boost::asio</code>), and <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a>. <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> Flow module somewhat streamlines this API in such a way as to keep the user's focus on their conceptual async-task-driven algorithm as opposed to details of threads, handlers, cores, etc. The <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> opaque type is central to this streamlined API, plus the central class <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>.<ul>
<li>The bottom line is the user thinks about their algorithm in terms of tasks; while the internals of the chosen <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> concrete object worry about the actual scheduling of these tasks across threads.</li>
</ul>
</li>
<li>boost.asio doesn't really provide ways to specify how threads should be assigned to processor cores; it only controls what code is executed on which thread. These abilities are available natively. <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> Flow module allows one to set certain knobs controlling this behavior, and the user can continue to only worry about their algorithm and not threading details.<ul>
<li>The combination of the generalized <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> mechanism and these thread-hardware-scheduling features in an integrated whole is what hopefully makes the Flow <code>async</code> module a value-add over just boost.asio, or over just boost.asio with some thread-core-affinity utility functions on the side.</li>
</ul>
</li>
</ul>
<dl class="section see"><dt>See also</dt><dd>The central type is the interface class <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>. For single-thread <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">async</a> work, which is very common, see <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html" title="A Concurrent_task_loop-related adapter-style class that represents a single-thread task loop; essenti...">Single_thread_task_loop</a>, a simplified adapter, similar to how <code>std::queue&lt;T&gt;</code> is commongly a simplified <code>std::deque&lt;T&gt;</code> or <code>list</code> underneath. </dd>
<dd>
<a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a>. </dd></dl>
</div><h2 class="groupheader">Typedef Documentation</h2>
<a id="a024042c64b7dc544a7a5587afa4b1949" name="a024042c64b7dc544a7a5587afa4b1949"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a024042c64b7dc544a7a5587afa4b1949">&#9670;&nbsp;</a></span>Op</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">flow::async::Op</a> = typedef boost::any</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>An object of this opaque type represents a collection of 1 or more <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72" title="Short-hand for a task that can be posted for execution by a Concurrent_task_loop or flow::util::Task_...">async::Task</a>, past or future, such that: <em>if</em> one performs <code>C-&gt;post(J, F)</code> and <code>C-&gt;post(K, G)</code> (where C is <code>Concurrent_task_loop*</code>, JK are the same <code><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a>&amp;</code>, or one refers to a transitive copy of the other, and FG are both <code>Task</code>s), <em>then</em> F and G will NOT execute concurrently. </p>
<p >In addition, it is guaranteed that copying (via constructor or assignment) of <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> is has performance characteristics no worse than those of <code>shared_ptr</code>. I.e., it is to be thought of as light-weight.</p>
<p >The value <code><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">Op()</a></code> is designated as a null/sentinel value and must not be passed to <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#a24f96f97ee24bfabb06c8609bc0e94a6" title="Cause the given Task (function) to execute within the thread pool as soon as possible,...">Concurrent_task_loop::post()</a> or anything built on it.</p>
<p >That's the formal definition. We reiterate that copying these is cheap; and moreover two <code>Op</code>s such that one is a copy (of a copy, of a copy, of a copy...) of another, then these are conceptually isomorphic: they represent the same op, or collection of <code>Task</code>s that must never execute concurrently. Finally, tip: Don't think of an <code>Op</code> as a collection of 2+ <code>Task</code>s; but rather a tag or label that associates 2+ <code>Task</code>s with each other. (Also, nothing prevents an <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72" title="Short-hand for a task that can be posted for execution by a Concurrent_task_loop or flow::util::Task_...">async::Task</a> being a part of 2+ <code>Op</code>s simultaneously, though informally speaking it's arguably best not to make code maintainers grok such a design.)</p>
<p >By convention in comments we represent <code>Op</code>s with the letters J, K, L.</p>
<h3>When to use an <code>Op</code> versus just a stand-alone <code>Task</code>?</h3>
<p >When choosing a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#a24f96f97ee24bfabb06c8609bc0e94a6" title="Cause the given Task (function) to execute within the thread pool as soon as possible,...">Concurrent_task_loop::post()</a> (the one with <code>Op</code> vs. one without; or similar choices in more advanced cases), here are some things to remember. These can be derived independently and are only included as a convenience/refresher:</p>
<ul>
<li>An <code>Op</code> prevents <code>Task</code>s from executing concurrently. If there is exactly 1 thread in a pool, then they couldn't anyway, so an <code>Op</code> is not needed...<ul>
<li>...except as future-proofing, in case conceivably 1 thread might soon turn into 2+ after all.</li>
</ul>
</li>
<li>It is quite common to follow the pattern wherein, as the very last statement to execute within a <code>Task</code>, one <code>post()</code>s (or similar) exactly 1 <code>Task</code> to asynchronously execute next. Since it's the last statement, and <code>post()</code> and similar are explicitly thread-safe, this ensures the current and next <code>Task</code>s do not execute concurrently. So an <code>Op</code> is not needed...<ul>
<li>...except as future-proofing. It is sometimes easier to maintain, and more expressive to read, when many <code>Task</code>s are "officially" run under the banner of a single <code>Op</code>, even if some parts of the async handling of the "conceptual" operation are serial and hence don't technically require an <code>Op</code>. Example: In a web server it is reasonable to create an <code>Op</code> for the entire request, with all <code>Task</code>s (even serially called ones) being associated with that per-request <code>Op</code>; then, simply, no locking is necessary for per-request data structure(s). It's much easier to explain, "you don't need to lock 'em," vs. "you don't need to lock 'em,
      unless the logic changes in such a way as to...."</li>
</ul>
</li>
</ul>
<p >To be fair, those tips ignore performance; they implicitly assume using <code>Op</code> pointlessly (functionally, not stylistically, so) is otherwise "free." It is <em>not</em> free; depending on internal details using <code>Op</code> might involve a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> and/or pinning stuff to a specific thread. Informally, this is seldom a big deal in practice; but in performance-sensitive projects one must remember there is a cost. </p>

</div>
</div>
<a id="af8c06052dd887bc77444550a7c243154" name="af8c06052dd887bc77444550a7c243154"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af8c06052dd887bc77444550a7c243154">&#9670;&nbsp;</a></span>Scheduled_task</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">flow::async::Scheduled_task</a> = typedef <a class="el" href="namespaceflow_1_1util.html#aafa03984c5012ef7db2e7d01b6909a83">util::Scheduled_task</a></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Similar to <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72" title="Short-hand for a task that can be posted for execution by a Concurrent_task_loop or flow::util::Task_...">flow::async::Task</a> but used for scheduled-in-future tasks as opposed to to-be-run-ASAP tasks. </p>
<p >In practice it's the same thing but takes a single <code>bool</code> argument with the meaning explained in <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">util::schedule_task_from_now()</a> doc header (spoiler alert: whether it ran as scheduled or was short-fired by user, as of this writing).</p>
<dl class="section note"><dt>Note</dt><dd>Whenever a comment explains how <code>Task</code>s are dealt with, one may usually assume the same extends equally to a <code>Scheduled_task</code>, merely at a different point in time. We omit that explicit language for brevity; it is to be assumed. </dd></dl>

</div>
</div>
<a id="af35fb65bdea1a3a92929ec2c4a6a6b72" name="af35fb65bdea1a3a92929ec2c4a6a6b72"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af35fb65bdea1a3a92929ec2c4a6a6b72">&#9670;&nbsp;</a></span>Task</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">flow::async::Task</a> = typedef Function&lt;void ()&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for a task that can be posted for execution by a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> or <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">flow::util::Task_engine</a>; it is simply something callable via <code>()</code> with no arguments and returning nothing. </p>
<p >By convention in comments we represent <code>Task</code>s with the letters F, G, H. </p>

</div>
</div>
<a id="a968806f54b14c697fd76b3339a2bdbbf" name="a968806f54b14c697fd76b3339a2bdbbf"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a968806f54b14c697fd76b3339a2bdbbf">&#9670;&nbsp;</a></span>Task_engine_ptr</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">flow::async::Task_engine_ptr</a> = typedef boost::shared_ptr&lt;<a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">util::Task_engine</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for reference-counting pointer to a mutable <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a <code>boost::asio::io_context</code>). </p>
<p >This is generally how classes in the <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> hierarchy refer to their internally used <code>Task_engine</code>s but also in advanced cases may be communicated to their user. </p>

</div>
</div>
<h2 class="groupheader">Enumeration Type Documentation</h2>
<a id="a0a06794b16b72f2829ce3353557c8485" name="a0a06794b16b72f2829ce3353557c8485"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0a06794b16b72f2829ce3353557c8485">&#9670;&nbsp;</a></span>Synchronicity</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">enum class <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">flow::async::Synchronicity</a></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">strong</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Enumeration indicating the manner in which <a class="el" href="namespaceflow_1_1async.html#a24567271e97a67d3cae6bd8bf8dc63c4" title="An extension of boost.asio&#39;s post() and dispatch() free function templates, this free function templa...">asio_exec_ctx_post()</a>, and various boost.asio "post" operations like it or based on it, are to actually execute the given task in relation to when the "posting" routine, itself, returns control to its caller. </p>
<p >Basically it indicates whether the execution should be synchronous or asynchronous and how, if it all, to wait for its completion &ndash; or its initiation. The <code>enum</code> members' meanings are the key things to understand; and there's some discussion in their doc headers that might be useful as a boost.asio refresher. </p>
<table class="fieldtable">
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f" name="a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f"></a>S_ASYNC&#160;</td><td class="fielddoc"><p >Simply post the given task to execute asynchronously in some execution context &ndash; as soon as the context's scheduler deems wise but specifically <em>not</em> inside the posting routine itself; and return as soon as possible having thus posted it. </p>
<p >That is: work in the manner of boost.asio <code>post(Task_engine, F)</code>.</p>
<p >In particular, suppose you're calling <code>POST(F)</code> in this mode, where <code>POST()</code> is some posting routine controlling a thread pool P, and <code>F()</code> is the task; and suppose the scheduler would deem wise to run <code>F()</code> in some thread P.W in that pool (perhaps for load-balancing reasons). Then:</p><ul>
<li>If <code>POST()</code> is being called outside of pool P, or it is being called from a sibling thread P.W' but not W itself, then <code>F()</code> will run at some point in the future (possibly even concurrently with <code>POST()</code> itself), in thread P.W.<ul>
<li>One typical case is when some external user of P loads work onto P.</li>
<li>The other is if some task or completion handler already in P loads async work back onto its own pool P, but the scheduler decides it's best for it to run in a different thread than the posting code.<ul>
<li>This is only possible with 2 or more threads in P (by no means always the case).</li>
</ul>
</li>
</ul>
</li>
<li>If <code>POST()</code> is being called from W itself, meaning the scheduler decided that the task should load on the same thread as the posting task, then <code>F()</code> will run at some point in the future strictly after the <code>POST()</code> returns.<ul>
<li>This usually means some task or completion handler in pool P is loading async work back onto its own pool, and either that pool contains only 1 thread (so there is no other choice), or else the scheduler decided the calling thread is still the best choice for task <code>F()</code> at this time (e.g., maybe the other thread(s) are loaded with queued work).</li>
</ul>
</li>
</ul>
<p >Either way, <code>POST()</code> will return quickly. Then <code>F()</code> will either run concurrently or after this return &ndash; but never <em>in</em> <code>POST()</code> synchronously. </p>
</td></tr>
<tr><td class="fieldname"><a id="a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" name="a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25"></a>S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION&#160;</td><td class="fielddoc"><p >Same as <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f" title="Simply post the given task to execute asynchronously in some execution context – as soon as the conte...">Synchronicity::S_ASYNC</a> but the posting routine then waits as long as necessary for the given task to complete; and only then returns. </p>
<p >That is: work in the manner of boost.asio <code>post(Task_engine, F)</code>, but wait until <code>F()</code> actually runs and returns. This must only be used when posting from a thread <em>outside</em> the target thread pool; or undefined behavior will result.</p>
<dl class="section warning"><dt>Warning</dt><dd>One must <em>not</em> use this mode when posting onto a thread pool from inside that thread pool: boost.asio <code>post()</code>-like function by definition won't execute a task synchronously inside itself, yet by the definition of this mode it must also wait for the task to run and complete. So if <code>post()</code> (or similar) were to decide the task belongs on the calling thread, an inifinite block (deadlock) occurs, as it will be waiting for something to happen that the wait prevents from happening.</dd></dl>
<p>This mode is reminiscent of the promise/future concept and allows one to easily solve the age-old problem of "how do I ask a thread/pool to do a thing and then wait for get a result?". One might do this by manually using a promise/future pair; or even mutex/condition variable pair; but by using this such boiler-plate is reduced (along with fewer bugs).</p>
<dl class="section warning"><dt>Warning</dt><dd>Be aware that the wait for completion will block infinitely, if one were to do something that would prevent the task from ever running. When working with boost.asio <code>Task_engine</code>s, this may occur when one <code>stop()</code>s or simply destroys the <code>Task_engine</code> (though the time period during which one would have to do this is short, assuming the task is quick). Naturally the way to avoid this is by not stopping or destroying the execution context during a posting call in mode <code>S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</code>. For example, the <code>Task_engine::stop()</code> call might be placed in the same thread as the posting; then they cannot be concurrent. If this is triggered from a SIGTERM/INT handler, one might only set or post something that will trigger the destruction in an orderly fashion at the proper time as opposed to doing it directly from the sig handler itself. This warning isn't anything that should be particularly new &ndash; orderly shutdown is typically concerned with such logic anyway &ndash; but it seemed worth putting in perspective of the fact this mode involves a wait for something that doesn't necessarily ever run, unless you actively make sure it does.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000001">Todo:</a></b></dt><dd>Much like the promise/future mechanism provides optional timed wait functionality, it might make sense to provide the API ability to set an optional time limit for any wait invoked by <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a> or <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_START</a>. Probably best to add this only once a need clearly arises though. </dd></dl>
</td></tr>
<tr><td class="fieldname"><a id="a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" name="a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846"></a>S_ASYNC_AND_AWAIT_CONCURRENT_START&#160;</td><td class="fielddoc"><p >Same as <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f" title="Simply post the given task to execute asynchronously in some execution context – as soon as the conte...">Synchronicity::S_ASYNC</a> but the posting routine then waits as long as necessary for the given task to <em>just</em> about to begin executing concurrently (so that any subsequent <code>Task_engine::stop()</code> shall be unable to prevent it from executing and eventually finishing) &ndash; and only then returns. </p>
<p >This is most similar to <code>S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</code> but may improve responsiveness of the calling thread, if what one needs to achieve is a guarantee that <code>F()</code> <em>will definitely</em> execute and complete, but does <em>not</em> need to wait for this to happen. So it's a weapon against a "dangling" <code>post()</code> that might be followed immediately by <code>Task_engine::stop()</code> &ndash; while not blocking until the posted thing finishes.</p>
<dl class="section warning"><dt>Warning</dt><dd>One must <em>not</em> use this mode when posting onto a thread pool from inside that thread pool; as with <code>S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</code> that may hang the thread. </dd></dl>
</td></tr>
<tr><td class="fieldname"><a id="a0a06794b16b72f2829ce3353557c8485aff6bc53ee6c14f2eee463c06d9dff01f" name="a0a06794b16b72f2829ce3353557c8485aff6bc53ee6c14f2eee463c06d9dff01f"></a>S_OPPORTUNISTIC_SYNC_ELSE_ASYNC&#160;</td><td class="fielddoc"><p >Execute the given task synchronously, if the scheduler determines that the calling thread is in its thread pool <em>and</em> is the best thread for the task; otherwise act identically to <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f" title="Simply post the given task to execute asynchronously in some execution context – as soon as the conte...">Synchronicity::S_ASYNC</a>. </p>
<p >That is: work in the manner of boost.asio <code>dispatch(Task_engine, F)</code>. This can be useful for performance, since when the opportunity presents itself this way avoids exiting a task only to immediately enter the posted task, when one could just synchronously execute one after the other.</p>
<dl class="section warning"><dt>Warning</dt><dd>Do <em>not</em> presume to know when a given scheduler will actually decide it will invoke the given task synchronously, unless documentation very clearly explains such rules. Just because it can does not mean it will. For example, boost.asio <code>post()</code> says that the task "might" run synchronously when this is possible; not that it "will." Assumptions about when it might in fact do so can lead to subtle and difficult-to-reproduce bugs. (Example of broken assumptions: Suppose it's a 1-thread pool, and one posts F from task G. Surely it must run F synchronously &ndash; there's no other thread! But what if some other task or completion handler was already queued up to run before F was? That's not even the point though; the scheduler is still free to not do it, say because of some spurious lock-related logic that is there for some obscure performance reason.)</dd>
<dd>
If you choose to use this mode (or <code>dispatch()</code>-like routines in general), it is almost never a good idea to do so from anywhere except just before returning from a task (or from outside the thread pool). If called from the middle of a task, you now cannot be sure if A happens before B or B happens before A. Usually that makes things complicated unnecessarily. </dd></dl>
</td></tr>
</table>

</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="a24567271e97a67d3cae6bd8bf8dc63c4" name="a24567271e97a67d3cae6bd8bf8dc63c4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a24567271e97a67d3cae6bd8bf8dc63c4">&#9670;&nbsp;</a></span>asio_exec_ctx_post()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Execution_context &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::asio_exec_ctx_post </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Execution_context *&#160;</td>
          <td class="paramname"><em>exec_ctx</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">Synchronicity</a>&#160;</td>
          <td class="paramname"><em>synchronicity</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>An extension of boost.asio's <code>post()</code> and <code>dispatch()</code> free function templates, this free function template allows the user to more easily select the synchronicity behavior as the given task is posted onto the given execution context (<a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> or <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> at least). </p>
<p >It also adds TRACE logging including that book-ending the task's execution (aiding debugging, etc.). The <code>synchronicity</code> argument controls the specific way in which <code>task</code> is posted onto <code>*exec_ctx</code>; see <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485" title="Enumeration indicating the manner in which asio_exec_ctx_post(), and various boost....">Synchronicity</a> doc header.</p>
<p >This call causes <code>task</code> to execute in a thread controlled by <code>*exec_ctx</code>. The latter, at this time, must be either <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> or <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> (which itself is born of a <code>Task_engine</code>). It is likely that it will work equally well for other entities satisfying the boost.asio <code>ExecutionContext</code> concept (see boost.asio docs), but this is untested and not thought through formally, so officially such uses cause undefined behavior as of this writing.</p>
<p >Semantics can be found in <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485" title="Enumeration indicating the manner in which asio_exec_ctx_post(), and various boost....">Synchronicity</a> doc headers which are required reading before using this function. However, briefly and informally, the utility of this function is as follows:</p><ul>
<li><code>post()</code> works on a <code>Task_engine</code> or <code>Strand</code> already and equals mode <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f" title="Simply post the given task to execute asynchronously in some execution context – as soon as the conte...">Synchronicity::S_ASYNC</a>; with this function you'll get some added debug logging as well.</li>
<li><code>dispatch()</code> and <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485aff6bc53ee6c14f2eee463c06d9dff01f" title="Execute the given task synchronously, if the scheduler determines that the calling thread is in its t...">Synchronicity::S_OPPORTUNISTIC_SYNC_ELSE_ASYNC</a> are similarly related: same thing but more logging.</li>
<li><a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a> equals a <code>post()</code> with a promise/future pair, wherein the caller performs <code>unique_future.wait()</code> after the <code>post()</code>, while the task always sets <code>promise.set_value()</code> just before returning (and, again, more logging).</li>
<li>Lastly, <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_START</a> is similar, but the <code>promise.set_value()</code> executes just <em>before</em> executing <code>task()</code>. Hence any tasks queued before <code>task()</code> will first execute (same as previous bullet); and <em>then</em> <a class="el" href="namespaceflow_1_1async.html#a24567271e97a67d3cae6bd8bf8dc63c4" title="An extension of boost.asio&#39;s post() and dispatch() free function templates, this free function templa...">asio_exec_ctx_post()</a> will return, just as <code>task()</code> begins executing as opposed to wait for its completion. This is useful to prevent <code>E.stop()</code> after our return (where <code>E</code> is the <code>Task_engine</code> that either is or produced <code>*exec_ctx</code>) will be too late to prevent <code>task()</code> from executing and completing.</li>
</ul>
<p >In all cases, one gets more logging and arguably a bit of syntactic sugar, but <code>S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</code> and <code>S_ASYNC_AND_AWAIT_CONCURRENT_START</code> in particular eliminate quite a bit of tedious and hairy code and explanations.</p>
<p >Lastly, if <code>*exec_ctx</code> is currently not running, then the semantics described in <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485" title="Enumeration indicating the manner in which asio_exec_ctx_post(), and various boost....">Synchronicity</a> doc header still apply but are deferred until it does run. In particular in mode <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a> and <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_START</a> this function shall not return until <code>*exec_ctx</code> at least does begin running in at least 1 thread; while the other two modes reduce to <code>post()</code>, which returns immediately, leaving <code>task()</code> to run once <code>*exec_ctx</code> starts.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Execution_context</td><td><a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> or <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>. See note above regarding other possibilities. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use in this function. </td></tr>
    <tr><td class="paramname">exec_ctx</td><td>The execution context controlling the thread pool onto which to load the <code>task</code> for ASAP execution. </td></tr>
    <tr><td class="paramname">synchronicity</td><td>Controls the precise behavior. See above. </td></tr>
    <tr><td class="paramname">task</td><td>The task &ndash; taking no arguments and returning no value &ndash; to load onto <code>*exec_ctx</code>. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="af90c1e763d49c3f3033a74871e897394" name="af90c1e763d49c3f3033a74871e897394"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af90c1e763d49c3f3033a74871e897394">&#9670;&nbsp;</a></span>asio_handler_via_op()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Handler &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">auto flow::async::asio_handler_via_op </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td>
          <td class="paramname"><em>loop</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;&#160;</td>
          <td class="paramname"><em>op</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Handler &amp;&amp;&#160;</td>
          <td class="paramname"><em>handler</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Given a boost.asio <em>completion handler</em> <code>handler</code> for a boost.asio <code>async_*()</code> action on some boost.asio I/O object to be initiated in the immediate near future, returns a wrapped handler with the same signature to be passed as the handler arg to that <code>async_*()</code> action, so that <code>handler()</code> will execute non-concurrently with other tasks in <code>Op op</code>. </p>
<p >This is analogous to boost.asio's <code>bind_executor(Strand, Handler)</code> (which replaces boost.asio's now-deprecated <code>util::Strand::wrap(Handler)</code>).</p>
<p >The mechanics of using this are explained in <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> doc header. Using this in any other fashion leads to undefined behavior.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Handler</td><td>boost.asio handlers are, essentially, all <code>void</code>-returning but can take various arg sets. E.g., <a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a> (a/k/a <code>boost::asio::basic_waitable_timer</code>) expects a handler that takes only an <code>Error_code</code>; while <code>boost::asio::ip:tcp::socket::read_some()</code> expects one to take bytes-received <code>size_t</code> and an <code>Error_code</code>. This template supports all handlers via <code>auto</code> magic. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">loop</td><td>Active loop that spawned <code>Op op</code>. </td></tr>
    <tr><td class="paramname">op</td><td>See 3-arg <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#a24f96f97ee24bfabb06c8609bc0e94a6" title="Cause the given Task (function) to execute within the thread pool as soon as possible,...">Concurrent_task_loop::post()</a>. </td></tr>
    <tr><td class="paramname">handler</td><td>Completion handler for the boost.asio <code>async_*()</code> operation to be initiated soon. It may be <code>move</code>d and saved. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A completion handler that will act as <code>handler()</code> but also satisfying the constraints of <code>Op op</code>. </dd></dl>

</div>
</div>
<a id="a7f2f976a53191a3b0cd28898bb23c551" name="a7f2f976a53191a3b0cd28898bb23c551"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7f2f976a53191a3b0cd28898bb23c551">&#9670;&nbsp;</a></span>op_to_exec_ctx()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Exec_ctx_ptr &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">Exec_ctx_ptr op_to_exec_ctx </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td>
          <td class="paramname"><em>loop</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;&#160;</td>
          <td class="paramname"><em>op</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Template specialization model for operation that obtains the underlying execution context, such as a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> or <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>. </p>
<p >Each subclass (impl) of <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> shall provide a specialization of this template with <code>Exec_ctx_ptr</code> template param being the appropriate boost.asio-compatible execution context type for that loop type's <code>Op create_op()</code>.</p>
<p >The mechanics of using this are explained in <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> doc header. Beyond that please see the particular specialization's doc header.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Exec_ctx_ptr</td><td>A pointer type (raw or smart) pointing to an execution context type satisfying boost.asio's "execution context" concept. As of this writing the known values would be pointers to <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> and <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, but really it depends on the particular subclass of <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> for the <code>*loop</code> arg. See its doc header near the particular <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> subclass. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">loop</td><td>Loop object that, one way or another, generated and returned <code>op</code>. </td></tr>
    <tr><td class="paramname">op</td><td><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> from <code>*loop</code> from which to extract the execution context object on which you'd like to perform custom boost.asio work. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to a mutable execution context object. </dd></dl>

</div>
</div>
<a id="a5dad6aeb3cf4219833e18343bec0b423" name="a5dad6aeb3cf4219833e18343bec0b423"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5dad6aeb3cf4219833e18343bec0b423">&#9670;&nbsp;</a></span>op_to_exec_ctx&lt; Strand_ptr &gt;() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a2b92feccafa90bce16db57131c0fcd9e">Strand_ptr</a> <a class="el" href="namespaceflow_1_1async.html#a7f2f976a53191a3b0cd28898bb23c551">op_to_exec_ctx</a>&lt; <a class="el" href="namespaceflow_1_1async.html#a2b92feccafa90bce16db57131c0fcd9e">Strand_ptr</a> &gt; </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td>
          <td class="paramname"><em>loop</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;&#160;</td>
          <td class="paramname"><em>op</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>. </p>
<p >boost.asio tip: The returned <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> may be useful not only as an argument to <code>bind_executor()</code> (formerly <code>Strand::wrap()</code>, now deprecated) but can also be passed in lieu of a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> into boost.asio-enabled I/O object constructors (<a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a>, <code>boost::asio::ip::tcp::socket</code>, etc.). The latter use uses the <code>Strand</code> as an "execution context."</p>
<p >Note <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#ac446f6bfed9fb54d073a5f3f578ec4bb" title="Returns a pointer to an internal util::Task_engine (a/k/a boost.asio io_context) for the purpose of p...">Concurrent_task_loop::task_engine()</a> is spiritually related to this function; but while that one gives one a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, which corresponds to the entire thread pool, this one returns an execution context specifically assigned to a multi-step async op <code>op</code>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> doc header for discussion.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">loop</td><td>Loop object that, one way or another, generated and returned <code>op</code>. Behavior is undefined if the concrete pointed-to type is not <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>. (assertion may trip). </td></tr>
    <tr><td class="paramname">op</td><td><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> from <code>*loop</code> from which to extract the execution context on which you'd like to perform custom boost.asio work. Behavior is undefined if it is not from <code>*loop</code> (assertion may trip). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to a mutable <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> created from <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> <code>E</code> such that <code>loop-&gt;task_engine() == &amp;E</code>. </dd></dl>

</div>
</div>
<a id="a05632ba834a42315615900ee4382287d" name="a05632ba834a42315615900ee4382287d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a05632ba834a42315615900ee4382287d">&#9670;&nbsp;</a></span>op_to_exec_ctx&lt; Strand_ptr &gt;() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a2b92feccafa90bce16db57131c0fcd9e">Strand_ptr</a> <a class="el" href="namespaceflow_1_1async.html#a7f2f976a53191a3b0cd28898bb23c551">flow::async::op_to_exec_ctx</a>&lt; <a class="el" href="namespaceflow_1_1async.html#a2b92feccafa90bce16db57131c0fcd9e">Strand_ptr</a> &gt; </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td>
          <td class="paramname"><em>loop</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;&#160;</td>
          <td class="paramname"><em>op</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>. </p>
<p >boost.asio tip: The returned <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> may be useful not only as an argument to <code>bind_executor()</code> (formerly <code>Strand::wrap()</code>, now deprecated) but can also be passed in lieu of a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> into boost.asio-enabled I/O object constructors (<a class="el" href="namespaceflow_1_1util.html#ae7416d64d2989051104bb396e28e15e6" title="boost.asio timer.">util::Timer</a>, <code>boost::asio::ip::tcp::socket</code>, etc.). The latter use uses the <code>Strand</code> as an "execution context."</p>
<p >Note <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#ac446f6bfed9fb54d073a5f3f578ec4bb" title="Returns a pointer to an internal util::Task_engine (a/k/a boost.asio io_context) for the purpose of p...">Concurrent_task_loop::task_engine()</a> is spiritually related to this function; but while that one gives one a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, which corresponds to the entire thread pool, this one returns an execution context specifically assigned to a multi-step async op <code>op</code>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> doc header for discussion.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">loop</td><td>Loop object that, one way or another, generated and returned <code>op</code>. Behavior is undefined if the concrete pointed-to type is not <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a>. (assertion may trip). </td></tr>
    <tr><td class="paramname">op</td><td><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> from <code>*loop</code> from which to extract the execution context on which you'd like to perform custom boost.asio work. Behavior is undefined if it is not from <code>*loop</code> (assertion may trip). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to a mutable <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a> created from <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> <code>E</code> such that <code>loop-&gt;task_engine() == &amp;E</code>. </dd></dl>

</div>
</div>
<a id="ad70c594985b402d9024b80370611fc1c" name="ad70c594985b402d9024b80370611fc1c"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad70c594985b402d9024b80370611fc1c">&#9670;&nbsp;</a></span>op_to_exec_ctx&lt; Task_engine_ptr &gt;() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> <a class="el" href="namespaceflow_1_1async.html#a7f2f976a53191a3b0cd28898bb23c551">op_to_exec_ctx</a>&lt; <a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> &gt; </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td>
          <td class="paramname"><em>loop</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;&#160;</td>
          <td class="paramname"><em>op</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>. </p>
<p >While <code>*loop</code> is running, the Task_engine is running in exactly 1 thread.</p>
<p >Note <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#ac446f6bfed9fb54d073a5f3f578ec4bb" title="Returns a pointer to an internal util::Task_engine (a/k/a boost.asio io_context) for the purpose of p...">Concurrent_task_loop::task_engine()</a> is spiritually related to this function; but while that one gives one a random thread's <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, this one returns the specific thread's assigned to a multi-step async op <code>op</code>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> doc header for discussion.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">loop</td><td>Loop object that, one way or another, generated and returned <code>op</code>. Behavior is undefined if the concrete pointed-to type is not <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>. (assertion may trip). </td></tr>
    <tr><td class="paramname">op</td><td><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> from <code>*loop</code> from which to extract the execution context on which you'd like to perform custom boost.asio work. Behavior is undefined if it is not from <code>*loop</code> (assertion may trip). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to a mutable <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> <code>E</code> used by <code>*loop</code>. </dd></dl>

</div>
</div>
<a id="ad932f51435b1776625df394e159e7e55" name="ad932f51435b1776625df394e159e7e55"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad932f51435b1776625df394e159e7e55">&#9670;&nbsp;</a></span>op_to_exec_ctx&lt; Task_engine_ptr &gt;() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;&gt; </div>
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> <a class="el" href="namespaceflow_1_1async.html#a7f2f976a53191a3b0cd28898bb23c551">flow::async::op_to_exec_ctx</a>&lt; <a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> &gt; </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td>
          <td class="paramname"><em>loop</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949">Op</a> &amp;&#160;</td>
          <td class="paramname"><em>op</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Template specialization for operation that obtains the underlying execution context, in this case a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, stored in an <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> generated by the given <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>. </p>
<p >While <code>*loop</code> is running, the Task_engine is running in exactly 1 thread.</p>
<p >Note <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#ac446f6bfed9fb54d073a5f3f578ec4bb" title="Returns a pointer to an internal util::Task_engine (a/k/a boost.asio io_context) for the purpose of p...">Concurrent_task_loop::task_engine()</a> is spiritually related to this function; but while that one gives one a random thread's <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, this one returns the specific thread's assigned to a multi-step async op <code>op</code>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> doc header for discussion.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">loop</td><td>Loop object that, one way or another, generated and returned <code>op</code>. Behavior is undefined if the concrete pointed-to type is not <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a>. (assertion may trip). </td></tr>
    <tr><td class="paramname">op</td><td><a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> from <code>*loop</code> from which to extract the execution context on which you'd like to perform custom boost.asio work. Behavior is undefined if it is not from <code>*loop</code> (assertion may trip). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Pointer to a mutable <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> <code>E</code> used by <code>*loop</code>. </dd></dl>

</div>
</div>
<a id="adab04f47b40b92fffbe12bc33fadd223" name="adab04f47b40b92fffbe12bc33fadd223"></a>
<h2 class="memtitle"><span class="permalink"><a href="#adab04f47b40b92fffbe12bc33fadd223">&#9670;&nbsp;</a></span>optimal_worker_thread_count_per_pool()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">unsigned int flow::async::optimal_worker_thread_count_per_pool </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>est_hw_core_sharing_helps_algo</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Assuming a planned thread pool will be receiving ~symmetrical load, and its UX-affecting (in particular, per-op latency-affecting) operations are largely between processor and RAM: Returns the # of threads to store in that pool for efficient performance. </p>
<dl class="section see"><dt>See also</dt><dd>After the threads are created, use <a class="el" href="namespaceflow_1_1async.html#a3e200db7e5375de21d2568004a85dcad" title="Assuming the same situation as documented for optimal_worker_thread_count_per_pool(),...">optimize_pinning_in_thread_pool()</a> to complete the work that targets this good performance.</dd></dl>
<p>This will be used, by doc header contract, by all (as of this writing) <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> subclasses if so specified via <code>n_threads_or_zero == 0</code>. So in that context one needn't call this directly. However, it may be useful directly when one is operating a thread pool but without a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use in this function. </td></tr>
    <tr><td class="paramname">est_hw_core_sharing_helps_algo</td><td>Set this to <code>true</code> if you estimate the intended use for this thread pool is such that 2+ identically loaded pool threads sharing 1 physical core would handle the load (in total over those 2+ threads) better than just 1 thread using that same core would. Set it to <code>false</code> otherwise. Note that, generally, this should be assumed <code>false</code>, unless there is significant cache locality between those 2+ threads, meaning they tend to work on the same cacheably-small area in memory at ~the same time. For example, parallel matrix multiplication algorithms can thus benefit and would set it to <code>true</code>; but that is the not the case by default; one would have to prove it, or design the algorithm with that in mind. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>The number of threads mandated for the thread pool in question. </dd></dl>

</div>
</div>
<a id="a3e200db7e5375de21d2568004a85dcad" name="a3e200db7e5375de21d2568004a85dcad"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3e200db7e5375de21d2568004a85dcad">&#9670;&nbsp;</a></span>optimize_pinning_in_thread_pool()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::optimize_pinning_in_thread_pool </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const std::vector&lt; <a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> * &gt; &amp;&#160;</td>
          <td class="paramname"><em>threads_in_pool</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>est_hw_core_sharing_helps_algo</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>est_hw_core_pinning_helps_algo</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">bool&#160;</td>
          <td class="paramname"><em>hw_threads_is_grouping_collated</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em> = <code>nullptr</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Assuming the same situation as documented for <a class="el" href="namespaceflow_1_1async.html#adab04f47b40b92fffbe12bc33fadd223" title="Assuming a planned thread pool will be receiving ~symmetrical load, and its UX-affecting (in particul...">optimal_worker_thread_count_per_pool()</a>, and that indeed the pool now contains that number of running threads: Attempts to optimize thread-core-pinning behavior in that pool for efficient performance. </p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1async.html#a7fa5292ae2e7dddd11a7fe5228b1e574" title="Resets the processor-affinity of the given thread – or calling thread – to be managed as the OS deems...">reset_thread_pinning()</a>: related operation.</dd></dl>
<h3>Error condition</h3>
<p >If an OS call fails, this will report error in standard Flow fashion. That said, this would indicate some sort of utter calamity of a situation; it might be reasonable to either both leave <code>err_code = null</code> and not-catch the exception; or abort the process on any error. In any case the situation will be logged.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1async.html#adab04f47b40b92fffbe12bc33fadd223" title="Assuming a planned thread pool will be receiving ~symmetrical load, and its UX-affecting (in particul...">optimal_worker_thread_count_per_pool()</a> first. The two functions work together (one before, the other after spawning the threads). Behavior is undefined if the two aren't used in coherent fashion, meaning one passed different values for same-named args.</dd></dl>
<dl class="section note"><dt>Note</dt><dd>There is a to-do, as of this writing, to allow one to query system to auto-determine <code>hw_threads_is_grouping_collated</code> if desired. See namespace <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> doc header.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use in this function. </td></tr>
    <tr><td class="paramname">threads_in_pool</td><td>These raw threads, which must number <code>optimal_worker_thread_count_per_pool(same-relevant-args)</code>, comprise the pool in question. They must be already spawned (e.g., have had some caller's code execute OK). </td></tr>
    <tr><td class="paramname">est_hw_core_sharing_helps_algo</td><td>See <a class="el" href="namespaceflow_1_1async.html#adab04f47b40b92fffbe12bc33fadd223" title="Assuming a planned thread pool will be receiving ~symmetrical load, and its UX-affecting (in particul...">optimal_worker_thread_count_per_pool()</a>. </td></tr>
    <tr><td class="paramname">est_hw_core_pinning_helps_algo</td><td>Set this to <code>true</code> if you have reason to believe that pinning each of the pool's threads to N (N &gt;= 1) logical cores would improve performance in some way. Set it to <code>false</code> otherwise. As of this writing I don't know why it would be <code>true</code> specifically; but it can be researched; and I know in practice some applications do (in fact) do it, so it's not necessarily worthless, at least. </td></tr>
    <tr><td class="paramname">hw_threads_is_grouping_collated</td><td>When the number of physical cores does not equal # of logical cores (hardware threads) &ndash; otherwise this arg is ignored &ndash; this determines the pattern in which each set of 2+ core-sharing hardware threads is arranged vs. the other sets. When <code>false</code>, it's like ABCDABCD, meaning logical cores 0,4 share core, 1,5 share different core, 2,6 yet another, etc. When <code>true</code>, it's like AABBCCDD instead. It seems <code>true</code> is either rare or non-existent, but I do not know for sure. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code><a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09" title="Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...">flow::Error_code</a></code> docs for error reporting semantics. <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09" title="Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...">Error_code</a> generated: various native system errors. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a227e64eb71ec278f19d679d8411db627" name="a227e64eb71ec278f19d679d8411db627"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a227e64eb71ec278f19d679d8411db627">&#9670;&nbsp;</a></span>reset_this_thread_pinning()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::reset_this_thread_pinning </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Resets processor-affinity of the calling thread; does not log; and throws on extremely unlikely system error. </p>
<p >That is: simply calls <code><a class="el" href="namespaceflow_1_1async.html#a7fa5292ae2e7dddd11a7fe5228b1e574" title="Resets the processor-affinity of the given thread – or calling thread – to be managed as the OS deems...">reset_thread_pinning()</a></code>. </p><dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1async.html#a7fa5292ae2e7dddd11a7fe5228b1e574" title="Resets the processor-affinity of the given thread – or calling thread – to be managed as the OS deems...">reset_thread_pinning()</a>.</dd></dl>
<p>This variant exists, so that one can pass it directly to APIs that expect a function object/pointer with signature <code>void F()</code>; for example <code>std::function&lt;void ()&gt;</code> ctor or <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">Single_thread_task_loop::start()</a>.</p>
<p >It is unfortunately not possible to, e.g., supply one of the form <code>void F(some_type some_arg = some_default)</code>: the compiler doesn't like the presence of any args, even if they all have defaults. </p>

</div>
</div>
<a id="a7fa5292ae2e7dddd11a7fe5228b1e574" name="a7fa5292ae2e7dddd11a7fe5228b1e574"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7fa5292ae2e7dddd11a7fe5228b1e574">&#9670;&nbsp;</a></span>reset_thread_pinning()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::reset_thread_pinning </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em> = <code>nullptr</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#af030c3119f060a9630afca31098a78a5">util::Thread</a> *&#160;</td>
          <td class="paramname"><em>thread_else_ours</em> = <code>nullptr</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em> = <code>nullptr</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Resets the processor-affinity of the given thread &ndash; or calling thread &ndash; to be managed as the OS deems best. </p>
<p >The variant <a class="el" href="namespaceflow_1_1async.html#a227e64eb71ec278f19d679d8411db627" title="Resets processor-affinity of the calling thread; does not log; and throws on extremely unlikely syste...">reset_this_thread_pinning()</a>, equivalent to <a class="el" href="namespaceflow_1_1async.html#a7fa5292ae2e7dddd11a7fe5228b1e574" title="Resets the processor-affinity of the given thread – or calling thread – to be managed as the OS deems...">reset_thread_pinning()</a> with args set to defaults, is suitable to be passed to APIs that take a <code>void F()</code> function object or function pointer; for example <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">Single_thread_task_loop::start()</a>:</p>
<div class="fragment"><div class="line"><a class="code hl_class" href="classflow_1_1async_1_1Single__thread__task__loop.html">flow::async::Single_thread_task_loop</a> strong_confident_independent_thread{...};</div>
<div class="line"><span class="comment">// It would inherit my core-affinity... so have it reset that early-on.</span></div>
<div class="line">strong_confident_independent_thread.<a class="code hl_function" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5">start</a>(<a class="code hl_function" href="namespaceflow_1_1async.html#a227e64eb71ec278f19d679d8411db627">flow::async::reset_this_thread_pinning</a>);</div>
<div class="line">strong_confident_independent_thread.post([]()</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Do stuff!  Won&#39;t be tied down to any core(s)!</span></div>
<div class="line">});</div>
<div class="ttc" id="aclassflow_1_1async_1_1Single__thread__task__loop_html"><div class="ttname"><a href="classflow_1_1async_1_1Single__thread__task__loop.html">flow::async::Single_thread_task_loop</a></div><div class="ttdoc">A Concurrent_task_loop-related adapter-style class that represents a single-thread task loop; essenti...</div><div class="ttdef"><b>Definition:</b> single_thread_task_loop.hpp:78</div></div>
<div class="ttc" id="aclassflow_1_1async_1_1Single__thread__task__loop_html_a0886e7f19d0c8b19f74851578802a5e5"><div class="ttname"><a href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5">flow::async::Single_thread_task_loop::start</a></div><div class="ttdeci">void start(Task &amp;&amp;init_task_or_empty=Task())</div><div class="ttdoc">Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...</div><div class="ttdef"><b>Definition:</b> single_thread_task_loop.cpp:41</div></div>
<div class="ttc" id="anamespaceflow_1_1async_html_a227e64eb71ec278f19d679d8411db627"><div class="ttname"><a href="namespaceflow_1_1async.html#a227e64eb71ec278f19d679d8411db627">flow::async::reset_this_thread_pinning</a></div><div class="ttdeci">void reset_this_thread_pinning()</div><div class="ttdoc">Resets processor-affinity of the calling thread; does not log; and throws on extremely unlikely syste...</div><div class="ttdef"><b>Definition:</b> concurrent_task_loop.cpp:309</div></div>
</div><!-- fragment --><h3>Rationale</h3>
<p >This might be useful in the face of the fact that at least some OS (Linux is one), when spawning thread T2 from thread T1, by default have T2 inherit the processor-affinity of T1; so for example if T1 is pinned to core 7, so will the new thread T2 be pinned to core 7 by default. This may be desirable &ndash; or not.</p>
<p >In particular, a general library that starts background work threads, especially ones with which the lib's user does not interact, might not want the default inheriting behavior but rather a thread behaving as independently and efficiently as possible.</p>
<p >Alternatively maybe you just want to undo <a class="el" href="namespaceflow_1_1async.html#a3e200db7e5375de21d2568004a85dcad" title="Assuming the same situation as documented for optimal_worker_thread_count_per_pool(),...">optimize_pinning_in_thread_pool()</a> or something.</p>
<h3>Error condition</h3>
<p >See same section in <a class="el" href="namespaceflow_1_1async.html#a3e200db7e5375de21d2568004a85dcad" title="Assuming the same situation as documented for optimal_worker_thread_count_per_pool(),...">optimize_pinning_in_thread_pool()</a> doc header.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for logging inside. An INFO message may be logged. Null is as always allowed. </td></tr>
    <tr><td class="paramname">thread_else_ours</td><td>The thread to affect; leave null to affect the calling thread. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code><a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09" title="Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...">flow::Error_code</a></code> docs for error reporting semantics. <a class="el" href="namespaceflow.html#a29eaaa9d0fac4ce87d8b969222dbed09" title="Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...">Error_code</a> generated: various native system errors. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:32 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
